import { ref, computed, unref, Ref } from 'vue';

// 权限类型定义
export type Permission = string | number
export type UserRole = string | number

export interface UserInfo {
  id: number | string
  name: string
  role: UserRole
  permissions?: Permission[]
}

export interface PermissionOptions {
  // 严格模式：必须同时满足角色和权限
  strict?: boolean
  // 权限验证逻辑
  validate?: (_permission: Permission, _user: UserInfo) => boolean
}

/**
 * 按钮权限控制 Hooks
 */
export function usePermission(options: PermissionOptions = {}) {
  const { strict = false, validate } = options;
  
  // 当前用户信息
  const userInfo: Ref<UserInfo> = ref({
    id: '',
    name: '',
    role: 'guest',
    permissions: []
  });

  // 权限映射表
  const permissionMap = ref(new Map<UserRole, Permission[]>());

  /**
   * 设置用户信息
   */
  const setUser = (user: UserInfo) => {
    userInfo.value = user;
  };

  /**
   * 设置权限映射
   */
  const setPermissionMap = (map: Map<UserRole, Permission[]>) => {
    permissionMap.value = map;
  };

  /**
   * 添加角色权限
   */
  const addRolePermissions = (role: UserRole, permissions: Permission[]) => {
    permissionMap.value.set(role, permissions);
  };

  /**
   * 获取用户权限列表
   */
  const getUserPermissions = computed(() => {
    const user = unref(userInfo);
    const rolePermissions = permissionMap.value.get(user.role) || [];
    
    // 合并角色权限和用户特定权限
    return [...new Set([...rolePermissions, ...(user.permissions || [])])];
  });

  /**
   * 检查是否有权限
   */
  const hasPermission = (permission: Permission): boolean => {
    const user = unref(userInfo);
    
    // 使用自定义验证逻辑
    if (validate) {
      return validate(permission, user);
    }

    // 超级管理员拥有所有权限
    if (user.role === 'super-admin') {
      return true;
    }

    const userPermissions = unref(getUserPermissions);
    
    // 检查权限
    const hasPerm = userPermissions.includes(permission);
    
    // 严格模式：必须同时满足角色和权限检查
    if (strict) {
      return hasPerm && user.role !== 'guest';
    }
    
    return hasPerm;
  };

  /**
   * 检查是否有任意一个权限
   */
  const hasAnyPermission = (permissions: Permission[]): boolean => {
    return permissions.some(permission => hasPermission(permission));
  };

  /**
   * 检查是否有所有权限
   */
  const hasAllPermissions = (permissions: Permission[]): boolean => {
    return permissions.every(permission => hasPermission(permission));
  };

  /**
   * 检查角色
   */
  const hasRole = (role: UserRole): boolean => {
    return unref(userInfo).role === role;
  };

  /**
   * 检查是否有任意一个角色
   */
  const hasAnyRole = (roles: UserRole[]): boolean => {
    return roles.includes(unref(userInfo).role);
  };

  return {
    // 状态
    userInfo: computed(() => userInfo.value),
    userPermissions: getUserPermissions,
    permissionMap: computed(() => permissionMap.value),
    
    // 设置方法
    setUser,
    setPermissionMap,
    addRolePermissions,
    
    // 检查方法
    hasPermission,
    hasAnyPermission,
    hasAllPermissions,
    hasRole,
    hasAnyRole
  };
}

/**
 * 创建权限指令
 */
export function createPermissionDirective(permissionHook: ReturnType<typeof usePermission>) {
  return {
    mounted(el: HTMLElement, binding: any) {
      const { value } = binding;
      
      if (!value) return;
      
      let permissions: Permission[] = [];
      
      // 支持字符串、数组或对象格式
      if (typeof value === 'string') {
        permissions = [value];
      } else if (Array.isArray(value)) {
        permissions = value;
      } else if (typeof value === 'object') {
        permissions = value.permissions || [];
      }
      
      if (permissions.length > 0 && !permissionHook.hasAnyPermission(permissions)) {
        if (binding.modifiers.disable) {
          // 禁用模式
          el.classList.add('permission-disabled');
          el.setAttribute('disabled', 'true');
        } else if (binding.modifiers.hide) {
          // 隐藏模式
          el.style.display = 'none';
        } else {
          // 默认移除元素
          el.parentNode?.removeChild(el);
        }
      }
    }
  };
}

/**
 * 创建权限组件
 */
export const PermissionComponent  = {
  name: 'PermissionComponent ',
  props: {
    value: {
      type: [String, Array, Object],
      required: true
    },
    mode: {
      type: String,
      default: 'show', // 'show' | 'hide' | 'disable'
      validator: (value: string) => ['show', 'hide', 'disable'].includes(value)
    }
  },
  setup(props: any, { slots }: any) {
    const { hasAnyPermission } = usePermission();
    
    return () => {
      const { value, mode } = props;
      
      if (!value) {
        return slots.default?.();
      }
      
      let permissions: Permission[] = [];
      
      // 解析权限值
      if (typeof value === 'string') {
        permissions = [value];
      } else if (Array.isArray(value)) {
        permissions = value;
      } else if (typeof value === 'object') {
        permissions = value.permissions || [];
      }
      
      const hasPerm = permissions.length === 0 || hasAnyPermission(permissions);
      
      if (!hasPerm) {
        if (mode === 'hide') {
          return null;
        } else if (mode === 'disable') {
          return slots.default?.().map((vnode: any) => {
            if (vnode.component) {
              vnode.component.props.disabled = true;
            }
            vnode.props = {
              ...vnode.props,
              disabled: true,
              class: [...(vnode.props?.class || []), 'permission-disabled']
            };
            return vnode;
          });
        }
        return null;
      }
      
      return slots.default?.();
    };
  }
};